home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
asmutil
/
asm_n_z.zip
/
SPY.ASM
< prev
next >
Wrap
Assembly Source File
|
1987-05-11
|
16KB
|
386 lines
name spy
rt equ 0dh ; return
lf equ 0ah ; linefeed
eof equ 1ah ; end of file
ok_seg equ 1 ; flag for segment decode check
ok_off equ 2 ; flag for offset decode check
max_size equ 4095 ; maximum size for SPY search region
beep_delay equ 4 ; number of clock ticks between beeps
timer_count equ 597 ; frequency of beep = 1,193,180 / timer_count
code segment
assume cs:code, ds:code
org 0
key1 dw ? ; offset of int 20h instruction
; used to verify a PSP location
org 100h
begin: jmp start ; jump to program start location
;-------------------------------------------------------------------------------
; This copyright message appears when SPY.COM is "typed" to the screen.
;-------------------------------------------------------------------------------
db 8,8,8,' '
copyright db rt,lf,'SPY Copyright (C) 1987 by Charles Lazo III, v1.0'
db eof,8,' ',rt,lf,'$'
key2 dw 1234h ; keys used to determine prior load of SPY
key3 dw 5678h
oldint8 dd ? ; double word storage for old int 8 vector
beeps dw 0 ; number of beeps (notices) to send to user
delay dw 1 ; number of clock ticks 'til next beep
beep_on db 0 ; beep on/off status
spy_size dw ? ; number of bytes to spy on
resident db 0 ; indicates prior load of SPY (0 = none)
spy_location label dword
spy_off dw ? ; storage for value of offset for SPYing
spy_seg dw ? ; storage for value of segment for SPYing
;-------------------------------------------------------------------------------
; Comparisons of the spied region and the spy buffer (set up initially as a copy
; of the spied region) are made in this addition to the timer interrupt.
; Changes to the spied region are counted and the spy buffer is updated. The
; speaker is turned on and off here, but frequency is set during program
; initialization.
;-------------------------------------------------------------------------------
newint8 proc near
push ax ; save interrupted program's registers
push bx
push cx
push si
push di
push ds
push es
mov ax,cs ; our data lies here
mov ds,ax
lea si,spy_buffer ; point to our buffer
les di,spy_location ; point to spied region
mov cx,spy_size ; compare whole region
cld ; forward!
cmp_more: repz cmpsb ; compare until no match or cx = 0
jz cmp_done ; if zero, then cx = 0 and we're done
inc beeps ; account for a change
mov al,es:[di-1] ; change accounted; update spy_buffer
mov [si-1],al
or cx,cx ; set zero flag by cx (avoid inf loop)
jmp short cmp_more ; continue 'til done
cmp_done: cmp beep_on,0 ; is the beep on?
jz do_beep? ; no, shall we do a beep?
dec beep_on ; yes, turn it off
in al,97 ; get speaker control bits
and al,0fch ; set them off
out 97,al ; turn off speaker
jmp short exit ; job done; get out
do_beep?: cmp beeps,0 ; are there beeps to be done?
jz delay1 ; no, get out
dec delay ; reduce delay 'til next beep
jnz exit ; not zero, then exit
in al,97 ; get speaker control bits
or al,3 ; set them on
out 97,al ; turn on speaker
inc beep_on ; signal beep is on
mov delay,beep_delay; reinitialize delay counter
dec beeps ; one less beep to do
jmp short exit ; leave now
delay1: mov delay,1 ; don't wait for first beep of a series
exit: pop es ; restore registers
pop ds
pop di
pop si
pop cx
pop bx
pop ax
jmp dword ptr cs:oldint8 ; continue with interrupt
newint8 endp
;-------------------------------------------------------------------------------
; Here the region spied upon is copied to an area of the TSR that remains in
; memory after termination, the spy_buffer. The es register is equal either to
; cs if SPY has not yet been loaded or to the value of cs when SPY was loaded
; previously (accomplished by a call to the set_es routine).
;-------------------------------------------------------------------------------
copy_spied: lea di,spy_buffer ; destination of copy
mov si,spy_off ; the offset is source of copy
mov cx,spy_size ; number of bytes to copy
mov ax,spy_seg ; load segment of SPY region to ds
push ds ; SOD (save our data)
mov ds,ax
cld ; forward copy
rep movsb ; copy the SPY region to spy_buffer
pop ds ; RestoreOD
cmp resident,0 ; is SPY currently resident in memory?
je tsr ; no, make it so
mov ax,4c00h ; yes, end with error code 0
int 21h
;-------------------------------------------------------------------------------
; SPY has not yet been loaded into memory, so we do it now. First the 8253-5
; chip that generates the frequency of the beeps is initialized with the value
; given by the constant timer_count. Then the new interrupt 8 routine is
; spliced in and finally the constant max_size is used to reserve enough memory
; for the largest permissible spy buffer.
;-------------------------------------------------------------------------------
tsr: mov delay,beep_delay; initialize delay counter
; set 8253-5 programmable timer to chosen frequency
mov al,182 ; byte to initialize 8253 timer
out 67,al ; tell timer next two bytes are count
mov ax,timer_count ; get timer count
out 66,al ; output low byte
mov al,ah
out 66,al ; output high byte
mov ax,3508h ; get the interrupt 8 (clock) vector
int 21h ; with DOS function 35h call
; Retain offset and segment of interrupt 8 vector:
mov word ptr cs:oldint8,bx
mov word ptr cs:oldint8+2,es
lea dx,newint8 ; place offset in dx
mov ax,2508h ; set its pointer into interrupt table
int 21h ; with DOS function 25h call
lea dx,spy_buffer ; where SPY buffer begins
mov cx,max_size ; add the maximum size of the buffer:
add dx,cx
mov cl,4 ; compute number of paragraphs to save:
shr dx,cl ; bytes to paragraphs in dx
inc dx ; insure sufficient size for buffer
mov ax,3100h ; terminate but stay resident code = 0
int 21h
;-------------------------------------------------------------------------------
; The following is initialization code and data that is overwritten by the data
; copied to the spy buffer when this buffer is initialized with a copy of the
; spied region.
;-------------------------------------------------------------------------------
spy_buffer: ; this is where SPY will store a copy of the SPY region
; to later check for any changes to the region
syntax db rt,lf,'SPY syntax: SPY xxxx:yyyy L zzz',rt,lf,rt,lf
db 'Where xxxx, and yyyy are hexadecimal numbers up to '
db 'four digits in length and',rt,lf
db 'zzz is a one to three digit hexadecimal number. SPY '
db 'will monitor the segment-',rt,lf
db 'offset region xxxx:yyyy for a length of zzz bytes and '
db 'report to the user with a',rt,lf
db 'number of beeps equal to the number of bytes changed '
db 'in that region if and when',rt,lf
db 'any are changed.',rt,lf,'$'
progress db 0 ; flags for progress of command line conversion
;-------------------------------------------------------------------------------
; This routine will convert an ASCII hex digit in al (either upper or lower case
; alpha hex) into a 1-of-16 binary value in al.
;-------------------------------------------------------------------------------
make_binary proc near ; hex ASCII digit in al to binary in al
cmp al,'0' ; less than "0", then not hex digit
jb not_digit
cmp al,'f' ; greater than "f", then not hex digit
ja not_digit
cmp al,'9' ; test for numeric digit
ja not_numeric ; not a numeric digit
sub al,'0' ; convert to binary
ret
not_numeric: cmp al,'F' ; over "F"?
ja low_case ; yes, test for lower case
cmp al,'A' ; less than "A"?
jb not_digit ; yes, not hex digit
sub al,37h ; convert to binary
ret
low_case: cmp al,'a' ; less than "a"?
jb not_digit ; yes, not hex digit
sub al,57h ; convert to binary
ret
not_digit: stc ; set carry flag if not hex digit
ret
make_binary endp
;-------------------------------------------------------------------------------
; This routine is called to allow the command line parse